ESP32とサーボ一個を使った無線で制御可能な入店・退店ゲートの試作
English version of this post is here.
はじめに
クラスメソッドが運営する「Developers.IO CAFE」に設置してあるレジレスの物品販売エリア(「ウォークスルー」と呼んでいます)には、入店・退店ゲートのようなものは現在設置されていません。ゲートを設置することで、お客様の購入体験を向上させられるか確認するために、ESP32とサーボ一個を使ったごく簡易的な入店・退店ゲートを試作してみました。本記事ではその試作の過程をご紹介します。
構想
- サーボモーターに、発泡スチロール等でできた棒を取り付けて90度の開閉を行わせる
- 水平状態がゲートオープン、垂直状態がゲートクローズ
- ESP32のBLE(GATT Write)でゲートの開閉を制御
- 秋月で売っているESP32-DevKitCを使用
- サーボ自体はPWM制御
- サーボモーター
- ヴィストンの「標準サーボモーター Type 2」
- カフェ内に設置してあるベルトパーテーションの支柱に固定する
- ゲートの開閉状態を示すバー
- スチレン製の棒を使用
- ハンズで売ってる、30mm経で1000mmの硬めのものを半分に切断して使用
- スチレン製の棒を使用
- カフェの物販システムと連携はしない
- 今回はまず動作確認できるモノを最速で作りたいので、カフェの物販システムと連携はしない
- BLE経由でマニュアル操作で開閉させる
- 今回はまず動作確認できるモノを最速で作りたいので、カフェの物販システムと連携はしない
試作
トルク計算
ゲートの開閉に使う棒には、ハンズで買ったスチレン製の棒を半分に切って使用します。この棒は1000mmで重量が約40gなので、半分(500mm)に切ると約20gになります。棒を水平にした時、500mmの棒の端に20gの荷重がかかると仮定すると、必要なトルクは0.02kgf x 0.5m = 0.01kgf・mとなります。今回使用するサーボのトルクはスペックによると4.6kgf・mあるので、十分余力がありそうです。
PWMによるサーボの制御
ESP32にはledc~~
という接頭辞の付いたLEDのPWM制御用の関数が用意されています。PWM制御という観点ではLEDもサーボも違いはありませんので、この関数でサーボのPWM制御を行います。弊社さかじのブログ記事で紹介されているシリアルポート経由の簡易的なCUIから値を送信して、動的にサーボのPWM制御ができることが確認できました。
BLEによる無線制御
ESP32のライブラリ関数を利用します。
コードサンプル
#include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> #define MIN 1 #define MAX 30 int n; int gate_open; BLEServer* pServer = NULL; BLECharacteristic* pCharacteristic = NULL; bool deviceConnected = false; bool oldDeviceConnected = false; #define SERVICE_UUID "YOUR OWN SERVICE UUID" #define CHARACTERISTIC_UUID "YOUR OWN CHARACTERISTIC UUID" String bleSensorName = "YOUR OWN BLE DEVICE NAME"; class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { Serial.println("onWrite"); std::string value = pCharacteristic->getValue(); if (value.length() > 0) { Serial.println("*********"); Serial.print("New value: "); for (int i = 0; i < value.length(); i++) Serial.print(value[i]); Serial.println(); Serial.println("*********"); } if (gate_open == 0) { n = 15; // 90° gate_open = 1; // GATE CLOSED } else { n = 1; // 0° gate_open = 0; // GATE OPENED } } }; void setup() { Serial.begin(115200); Serial.print("> "); ledcSetup(0, 50, 8); // 0ch 50 Hz 8bit resolution ledcAttachPin(15, 0); // 15pin, 0ch n = MIN; gate_open = 0; BLEDevice::init((char *)bleSensorName.c_str()); pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService *pService = pServer->createService(SERVICE_UUID); pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setCallbacks(new MyCallbacks()); // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml pCharacteristic->addDescriptor(new BLE2902()); pService->start(); pServer->getAdvertising()->start(); // start advertising Serial.println("Setup completed. starting advertising..."); } void loop() { if (Serial.available() > 0) { String s; s = Serial.readStringUntil('\n'); Serial.println(s); int new_n = menu(s); if (new_n != -1) n = new_n; } if (n > MAX) n = MAX; if (n < MIN) n = MIN; ledcWrite(0, n); // disconnecting if (!deviceConnected && oldDeviceConnected) { delay(500); // give the bluetooth stack the chance to get things ready pServer->startAdvertising(); // restart advertising Serial.println("start advertising"); oldDeviceConnected = deviceConnected; } // connecting if (deviceConnected && !oldDeviceConnected) { oldDeviceConnected = deviceConnected; } } int menu(String s) { if (s.equals("?")) { Serial.println("entrance-exit-gate-controller"); Serial.print("> "); return -1; } else if (s.equals("ver")) { Serial.println("0.0.1"); Serial.print("> "); return -1; } else { Serial.println(s); Serial.print("> "); return s.toInt(); } }
組み立て
今回の試作では、最低限の動作確認ができればOKなので、以下のような感じで超雑に組み立てました。サーボの電源(5V)はESP32-DevKitCの5V出力ピンから供給しました。
- サーボとESP32-DevKitCを養生テープでぐるぐる巻きにしてベルトパーテーションの支柱に固定
- スチレン製の棒の端の方にサーボの回転パーツを養生テープでぐるぐる巻きに固定
動作確認
以下が動作確認時の動画です。物販システムとは連動していないため、ゲートを開閉する際に手元のBLEクライアントアプリ経由で入店ゲートのESP32のCharacteristicにWriteしています。
おわりに
今回の試作でとりあえず動くモノができましたが、入店・退店ゲートとして本当に最低限の動作ができるだけの代物でしかありません。目先の課題として以下のようなものがありますので、これらをクリアしつつ、ゲートを設置することで、お客様の購入体験を向上させられるかの確認の実施までこぎつけたいと思います。
- カフェの物販システムと連携
- サーボと台座をきちんと固定する
- ゲートオープン・クローズのバーの見た目がしょぼいので、もうちょっと見栄えのよいモノにする
参考
- Developers.IO CAFE | クラスメソッド
- [小ネタ]あると便利ESP32とのシリアル通信 | DevelopersIO
- ESP32-DevKitC ESP-WROOM-32開発ボード: 無線、高周波関連商品 秋月電子通商-電子部品・ネット通販
- 標準サーボモーター Type 2 (4562179395647) : ロボットショップ / Robot Shop ロボット関連商品の専門店
- スチレンストック 径30×1000mm|【東急ハンズネットストア】
- ESP32 でサーボモーターを動かしてみた:息子と一緒に Makers:So-netブログ
- トルク - Wikipedia
- パルス幅変調 - Wikipedia